home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / icons+tools / iconian / sources / doloaddt.e < prev    next >
Text File  |  1995-12-22  |  57KB  |  1,844 lines

  1. /*
  2.     DoLoadDT.m  --  A datatype load, scale, remap and dither routine.
  3. */   
  4. /* $VER:doloaddt 0.88 (7.6.95) */
  5.  
  6. /*
  7.  
  8. THIS SOURCE IS COPYRIGHT 1994,1995 by Chad Randall, mbissaymssiK Software
  9.  
  10. If you wish to include this, or any modified version of this routine in your
  11. own program, you *MUST* credit me somewhere in your program and/or documentation.
  12.  
  13. I am distributing this source mainly for those who wish to learn a thing or two.
  14.  
  15. Please don't rip me off.
  16.  
  17. */
  18.  
  19.  
  20. OPT MODULE
  21.  
  22. OPT PREPROCESS
  23.  
  24. MODULE    'exec/memory','exec/types'
  25. MODULE    'dos/dos'
  26. MODULE    'intuition/intuition','intuition/screens','intuition/gadgetclass','intuition/imageclass'
  27. MODULE    'graphics/rastport','graphics/gfx','graphics/text','graphics/scale','graphics/view',
  28.                 'graphics/gfxbase','graphics/clip','graphics/layers','graphics/modeid'
  29. MODULE    'iffparse','libraries/iffparse'
  30. MODULE    'utility','utility/hooks','utility/tagitem'
  31. MODULE    'datatypes','datatypes/datatypes','datatypes/datatypesclass','datatypes/pictureclass'
  32. MODULE    'mathffp'
  33. MODULE    'gadtools','libraries/gadtools'
  34.  
  35. MODULE    'tools/boopsi'
  36.  
  37. MODULE    'mod/fonts'
  38. MODULE    'mod/bits'
  39. MODULE    'mod/compare'
  40. MODULE    'mod/gadgets'
  41. MODULE    'mod/macros'
  42. MODULE    'mod/pool'
  43. MODULE    'mod/color'
  44. MODULE    'mod/tags'
  45.  
  46. MODULE    'gaugeimage','class/gaugeimage'
  47.  
  48. EXPORT OBJECT sizestruct
  49.     font:LONG
  50.     x:INT
  51.     y:INT
  52.     type:CHAR
  53. ENDOBJECT
  54.  
  55. EXPORT OBJECT statwindow
  56.     scr:PTR TO screen
  57.     centerx:INT
  58.     centery:INT
  59.     textfont:PTR TO textfont
  60.     textattr:PTR TO textattr
  61.     textstyle:LONG
  62.     load_string:LONG
  63.     scale_string:LONG
  64.     histogram_string:LONG
  65.     quant_string:LONG
  66.     render_string:LONG
  67.     cancel_string:LONG
  68.     title_string:LONG
  69.     status_string:LONG
  70. ENDOBJECT
  71.  
  72. EXPORT OBJECT imageinfo
  73.     source_w:LONG
  74.     source_h:LONG
  75.     destination_x:LONG
  76.     destination_y:LONG
  77.     destination_w:LONG
  78.     destination_h:LONG
  79.     depth:LONG
  80.     highest_pen:LONG
  81.     statwindowx:LONG
  82.     statwindowy:LONG
  83.     reserved3:LONG
  84.     reserved4:LONG
  85.     reserved5:LONG
  86.     reserved6:LONG
  87.     reserved7:LONG
  88.     reserved8:LONG
  89.     blackpen:LONG
  90.     whitepen:LONG
  91.     greypen:LONG
  92. ENDOBJECT
  93.  
  94.  
  95.  
  96. EXPORT ENUM DLDT_CENTER=TAG_USER,            ->Centers image in w/h
  97.                         DLDT_INTEGERSCALE,                ->OBSOLETE
  98.                         DLDT_DITHER,                            ->
  99.                         DLDT_REMAP,                                ->Use FindColor to remap pens?
  100.                         DLDT_ASPECTX,                            ->x aspect value as in x:y
  101.                         DLDT_ASPECTY,                            ->y aspect value
  102.                         DLDT_SCALE,                                ->Should we scale, or crop? if=false then crop.
  103.                         DLDT_USEASPECT,                        ->Should we use the aspect values, or do 1:1 to 1:1?
  104.                         DLDT_ENLARGE,                            ->OBSOLETE
  105.                         DLDT_CLEAR,                                ->Clears from x->y, w->h
  106.                         DLDT_GAUGE,                                ->OBSOLETE
  107.                         DLDT_CLIGAUGE,                        ->A ptr to a STRING with an imbedded "%s" code.
  108.                         DLDT_HOOK,                                ->OBSOLETE
  109.                         DLDT_INFO,                                ->A ptr to a imageinfo struct to be filled in.
  110.                         DLDT_BIDIRECTIONAL,                ->OBSOLETE
  111.                         DLDT_DIARRAY,                            ->OBSOLETE
  112.                         DLDT_HIGHPEN,                            ->Highest pen to use, -1 for all available. (default)
  113.                         DLDT_FILLCMAP,                        -> Use DT cmap, and fill-in given cmap! no faint-hearts!!!
  114.                         DLDT_GREYSCALE,                        -> create greyscale icon
  115.                         DLDT_QUANTIZE,                        -> quantize to x number of colors
  116.                         DLDT_CUSTOMFINDCOLOR,            -> OBSOLETE
  117.                         DLDT_RENDERHAM,                        -> if =6 then HAM6, if =8 then HAM8, else normal
  118.                         DLDT_HAMTHRESHOLD,                -> specifies when to use base-4 colors
  119.                         DLDT_FULLHAMBASE,
  120.                         DLDT_DISCARDERROR,
  121.                         DLDT_STRETCHTOFIT,
  122.                         DLDT_NORENDER,
  123.                         DLDT_STATWINDOW,
  124.                         DLDT_ACTIVATESTATWINDOW,
  125.                         DLDT_DITHERTYPE,
  126.                         DLDT_QUANTTYPE,
  127.                         DLDT_SHOWSIZE
  128.  
  129. EXPORT ENUM DITH_ERRORDIFF,DITH_FLOYD,DITH_STUCKI,DITH_BURKES
  130. EXPORT ENUM QUANT_VERBATIM,QUANT_POPULARITY,QUANT_MEDIANCUT,QUANT_MEDIANCUT2,QUANT_MEDIANCUT3,QUANT_MEDIANCUT4,QUANT_MEDIANCUT5,QUANT_MEDIANCUT6,QUANT_MEDIANCUT7,QUANT_END
  131. EXPORT ENUM TEXT_NORMAL,TEXT_SHADOW,TEXT_OUTLINE
  132.  
  133. DEF dtlib,utillib,ifflib,mathlib
  134.  
  135.  
  136. #define PPM_GETR(p) (Shr(Shr(((p) AND $FF0000),8),8))
  137. #define PPM_GETG(p) (Shr(((p) AND $FF00),8))
  138. #define PPM_GETB(p) ((p) AND $FF)
  139.  
  140. #define PPM_PUTR(red) (Shl(Shl(((red) AND $FF),8),8))
  141. #define PPM_PUTG(grn) (Shl(((grn) AND $FF),8))
  142. #define PPM_PUTB(blu) ((blu) AND $FF)
  143.  
  144. #define PPM_ASSIGN(red,grn,blu) ((Shl(Shl(red AND $FF,8),8)) OR (Shl(grn AND $FF,8)) OR (blu AND $FF))
  145.  
  146. OBJECT box
  147.     ind:LONG            -> Where the box starts in the histogram
  148.     colors:LONG    -> The number of entries involved (colorcount)
  149.     sum:LONG        -> The number of pixels involved
  150.     redw:INT        -> The red width   (not scaled)  ^3 (volume)
  151.     grnw:INT        -> The green width (not scaled)
  152.     bluw:INT        -> The blue width  (not scaled)
  153.     red0:INT
  154.     grn0:INT
  155.     blu0:INT
  156.     red1:INT
  157.     grn1:INT
  158.     blu1:INT
  159. ENDOBJECT
  160.  
  161. CONST HASH_SIZE=20023
  162. CONST MAXCOLORS=32767
  163. #define HASHPIXEL(p) (Mod(((p) AND $ffffff),HASH_SIZE))
  164.  
  165. OBJECT colorhist_item
  166.     color:LONG
  167.     value:LONG
  168. ENDOBJECT
  169.  
  170. OBJECT colorhist_list_item
  171.     ch:colorhist_item
  172.     next:PTR TO colorhist_list_item
  173. ENDOBJECT
  174.  
  175. DEF statwindow:PTR TO window
  176. DEF gaugeobj
  177. DEF stat:PTR TO statwindow
  178. DEF histopool
  179. DEF drawinfo:PTR TO drawinfo
  180.  
  181. EXPORT PROC doloaddt(source,rast:PTR TO rastport,cmap:PTR TO colormap,x,y,w,h,taglist) HANDLE
  182.     DEF dtf=NIL:PTR TO dtframebox,fri=NIL:PTR TO frameinfo,obj=NIL:PTR TO datatypeheader,gpl=NIL:PTR TO gplayout
  183.     DEF dtrast=NIL:PTR TO rastport
  184.     DEF red[260]:LIST,grn[260]:LIST,blu[260]:LIST
  185.     DEF cregs,bm=NIL:PTR TO bitmap,bmhd=NIL:PTR TO bitmapheader,modeid
  186.     DEF norender=FALSE
  187.     DEF center,intscale=FALSE,dither=TRUE,remap=TRUE,aspectx=1,aspecty=1,scale=TRUE,useaspect=TRUE,enlarge=FALSE,clear=TRUE
  188.     DEF scalex,scaley,scalef
  189.     DEF res,res2
  190.     DEF trast=NIL:PTR TO rastport,tbm=NIL:PTR TO bitmap
  191.     DEF sfixx,sfixy
  192.     DEF ditz=0:PTR TO CHAR,dang=0:PTR TO CHAR,dumb=0:PTR TO CHAR,body:PTR TO CHAR
  193.     DEF usehighpen=-1
  194.     DEF fillcmap=FALSE
  195.     DEF cm
  196.     DEF hammode=FALSE,gaugestr=FALSE
  197.     DEF i,t,u,v,z,xpixper=1,ypixper=1,step,stop
  198.     DEF scalarx,scalary,percent,adjustw,adjusth,finalw,finalh,finalx,finaly
  199.     DEF linebuf=0:PTR TO CHAR,redbuf=0,grnbuf=0,blubuf=0
  200.     DEF dithermode=DITH_FLOYD
  201.     DEF showsize=0
  202.     DEF stretch=FALSE
  203.     DEF statx=0,staty=0,statw=0,stath=0
  204.     DEF statgad=0
  205.     DEF glist=0,gad
  206.     DEF tmp1=0:PTR TO CHAR,tmp2=0:PTR TO CHAR,tmp3=0:PTR TO CHAR
  207.     DEF tmp4=0:PTR TO LONG,tmp5,tmp6,tmp7,tmp8,ttmp1,ttmp2,ttmp3
  208.     DEF longptr:PTR TO LONG
  209.     DEF lmp4,lmp5,lmp6
  210.     DEF er1,er2,er3,er4
  211.     DEF eg1,eg2,eg3,eg4
  212.     DEF eb1,eb2,eb3,eb4
  213.     DEF sumred=0,sumgrn=0,sumblu=0,num=0
  214.     DEF fc,reddif,grndif,bludif,grabbuf=0:PTR TO CHAR
  215.     DEF realred[260]:LIST,realgrn[260]:LIST,realblu[260]:LIST
  216.     DEF vis=0
  217.     DEF iinfo=0:PTR TO imageinfo
  218.     DEF highpen=0
  219.     DEF activatewindow=FALSE
  220.     DEF speed1,speed6,speed7,speed8
  221.     DEF red24=0,grn24=0,blu24=0
  222.     DEF grey=0,quant=256
  223.     DEF hamr,hamg,hamb
  224.     DEF hadr,hadg,hadb
  225.     DEF renderham=0,hamthres=64
  226.     DEF hambase=3
  227.     DEF discard=FALSE
  228.     DEF quantmode=QUANT_MEDIANCUT
  229.     DEF histo:PTR TO LONG
  230.     DEF gaugeclass=0
  231.  
  232.     histo:=0;statwindow:=0;stat:=0
  233.     dtf:=New(600);fri:=New(600);gpl:=New(600)
  234.     dtrast:=New(SIZEOF rastport);InitRastPort(dtrast)
  235.     trast:=New(SIZEOF rastport);CopyMem(dtrast,trast,SIZEOF rastport);trast.layer:=0
  236.     
  237.     IF checklibs()=FALSE THEN Raise("LIB")
  238.     IF taglist
  239.         center:=findtag(taglist,DLDT_CENTER)
  240.         intscale:=findtag(taglist,DLDT_INTEGERSCALE)
  241.         dither:=findtag(taglist,DLDT_DITHER,TRUE)
  242.         remap:=findtag(taglist,DLDT_REMAP,TRUE)
  243.         aspecty:=findtag(taglist,DLDT_ASPECTX,1)
  244.         aspectx:=findtag(taglist,DLDT_ASPECTY,1)
  245.         scale:=findtag(taglist,DLDT_SCALE,TRUE)
  246.         useaspect:=findtag(taglist,DLDT_USEASPECT,TRUE)
  247.         enlarge:=findtag(taglist,DLDT_ENLARGE)
  248.         clear:=findtag(taglist,DLDT_CLEAR,TRUE)
  249.         gaugestr:=findtag(taglist,DLDT_CLIGAUGE)
  250.         iinfo:=findtag(taglist,DLDT_INFO)
  251.         usehighpen:=findtag(taglist,DLDT_HIGHPEN,-1)
  252.         fillcmap:=findtag(taglist,DLDT_FILLCMAP)
  253.         quant:=limit(findtag(taglist,DLDT_QUANTIZE,256),1,256)
  254.         grey:=limit(findtag(taglist,DLDT_GREYSCALE),0,2)
  255.         renderham:=limit(findtag(taglist,DLDT_RENDERHAM),0,8)
  256.         hamthres:=limit(findtag(taglist,DLDT_HAMTHRESHOLD,64),0,760)
  257.         speed8:=findtag(taglist,DLDT_FULLHAMBASE)
  258.         IF speed8
  259.             IF renderham=6
  260.                 hambase:=15
  261.             ELSE
  262.                 hambase:=63
  263.             ENDIF
  264.         ENDIF
  265.         discard:=findtag(taglist,DLDT_DISCARDERROR,discard)
  266.         stretch:=findtag(taglist,DLDT_STRETCHTOFIT,stretch)
  267.         norender:=findtag(taglist,DLDT_NORENDER,norender)
  268.         stat:=findtag(taglist,DLDT_STATWINDOW,stat)
  269.         activatewindow:=findtag(taglist,DLDT_ACTIVATESTATWINDOW,activatewindow)
  270.         dithermode:=findtag(taglist,DLDT_DITHERTYPE,dithermode)
  271.         quantmode:=findtag(taglist,DLDT_QUANTTYPE,quantmode)
  272.         showsize:=findtag(taglist,DLDT_SHOWSIZE)
  273.  
  274.          IF usehighpen=-1 THEN usehighpen:=256
  275.         IF (quant<256)
  276.             usehighpen:=limit(smaller(usehighpen,quant-1),1,255)
  277.         ENDIF
  278.     ENDIF
  279.  
  280.      IF stat
  281.         drawinfo:=GetScreenDrawInfo(stat.scr)
  282.         vis:=GetVisualInfoA(stat.scr, NIL)
  283.     ENDIF
  284.  
  285.      IF ((stat<>0) AND (drawinfo<>0) AND (vis<>0))
  286.          statw,stath:=biggest(rast,[stat.load_string,stat.scale_string,stat.histogram_string,stat.render_string,TAG_END]:LONG,stat.textfont,stat.textstyle)
  287.          tmp1,tmp2:=fontsize2(rast,stat.cancel_string,stat.textfont,stat.textstyle)
  288.          tmp8,tmp7:=fontsize2(rast,stat.status_string,stat.textfont,stat.textstyle)
  289.          statw:=bigger(bigger(statw,tmp1),tmp8)
  290.         tmp8:=bigger(tmp8,statw)
  291.          statx:=stat.centerx-(statw/2)
  292.          staty:=stat.centery-(stath/2)
  293.          tmp3:=(WFLG_SMART_REFRESH OR WFLG_DRAGBAR OR WFLG_DEPTHGADGET)
  294.          IF activatewindow THEN tmp3:=tmp3 OR WFLG_ACTIVATE
  295.          statwindow:=OpenWindowTagList(0,
  296.                                      [WA_INNERWIDTH,statw+16,
  297.                                         WA_INNERHEIGHT,stath+14+tmp2+tmp7,
  298.                                         WA_LEFT,statx,
  299.                                         WA_TOP,staty,
  300.                                         WA_FLAGS,tmp3,
  301.                                         WA_TITLE,stat.title_string,
  302.                                         WA_CUSTOMSCREEN,stat.scr,
  303.                                         WA_IDCMP,(BUTTONIDCMP OR IDCMP_REFRESHWINDOW),
  304.                                         WA_NEWLOOKMENUS,TRUE,
  305.                                         WA_AUTOADJUST,TRUE,
  306.                                         NIL])
  307.         SetAPen(statwindow.rport,2)
  308.         SetBPen(statwindow.rport,0)
  309.         setafpt(statwindow.rport,[%1010101010101010,%0101010101010101]:INT,1)
  310.         SetDrMd(statwindow.rport,RP_JAM2)
  311.         RectFill(statwindow.rport,statwindow.borderleft,statwindow.bordertop,rightedge(statwindow)-1,bottomedge(statwindow)-1)
  312.         setafpt(statwindow.rport,0,0)
  313.         
  314.         IF statwindow
  315.             gaugeclass:=Init_gaugeiclass()
  316.             gad:=CreateContext({glist})
  317.              tmp3:=(statwindow.width/2)-(tmp1/2)
  318.              tmp4:=(statwindow.height-statwindow.borderbottom-tmp2-3)
  319.             statgad,gad:=CreateGadgetA(BUTTON_KIND,gad,
  320.                                                 [tmp3-8,tmp4,tmp1+16,tmp2+2,stat.cancel_string,stat.textattr,1,0,vis,0]:newgadget,[NIL,NIL])
  321.             AddGList(statwindow,statgad,-1,-1,0)
  322.             RefreshGList(statgad,statwindow,0,-1)
  323.             disablegadget(statgad,statwindow)
  324.  
  325.             gaugeobj:=NewObjectA(gaugeclass,NIL,
  326.                  [IA_LEFT,statwindow.borderleft+2,
  327.                     IA_TOP,statwindow.bordertop+6+tmp7,
  328.                     IA_WIDTH,insidewidth(statwindow)-4,
  329.                     IA_HEIGHT,stath+4,
  330.                     GAUGEIA_TEXTFONT,stat.textfont,
  331.                     GAUGEIA_TEXTSTYLE,stat.textstyle,
  332.                     GAUGEIA_SCREEN,stat.scr,
  333.                     GAUGEIA_STYLE,GAUGETYPE_FANCY,
  334.                     TAG_END])
  335.  
  336.             tmp1:=(statwindow.width/2)-(tmp8/2)
  337.             tmp2:=statwindow.bordertop+2
  338.             drawbevelbox(vis,statwindow.rport,tmp1-6,tmp2,tmp8+12,tmp7+3,1,TRUE,0)
  339.             Move(statwindow.rport,tmp1,stat.textfont.baseline+tmp2+1)
  340.             SetAPen(statwindow.rport,1)
  341.             SetFont(statwindow.rport,stat.textfont)
  342.             Text(statwindow.rport,stat.status_string,StrLen(stat.status_string))
  343.             SetAttrsA(gaugeobj,[IA_DATA,stat.load_string,TAG_END])
  344.             DrawImageState(statwindow.rport,gaugeobj,0,0,IDS_INACTIVENORMAL,drawinfo)
  345.         ENDIF
  346.      ENDIF
  347.  
  348.     IF source<257
  349.         obj:=NewDTObjectA(source,[DTA_SOURCETYPE,DTST_CLIPBOARD,DTA_GROUPID,GID_PICTURE,PDTA_REMAP,FALSE,NIL,NIL])
  350.     ELSE
  351.         obj:=NewDTObjectA(source,[DTA_SOURCETYPE,DTST_FILE,DTA_GROUPID,GID_PICTURE,PDTA_REMAP,FALSE,NIL,NIL])
  352.     ENDIF
  353.     IF obj
  354.         PutLong(dtf,DTM_FRAMEBOX)
  355.         dtf.frameinfo:=fri
  356.         dtf.contentsinfo:=fri
  357.         dtf.sizeframeinfo:=SIZEOF frameinfo
  358.         IF (domethod(obj,dtf))
  359.             PutLong(gpl,DTM_PROCLAYOUT)
  360.             gpl.ginfo:=NIL
  361.             gpl.initial:=1
  362.             IF (domethod(obj,gpl))
  363.                 GetDTAttrsA(obj,[PDTA_CREGS,{cregs},PDTA_BITMAP,{bm},PDTA_BITMAPHEADER,{bmhd},PDTA_MODEID,{modeid},NIL,NIL])
  364.                 IF (modeid AND HAM_KEY);hammode:=TRUE;ENDIF
  365.                 dtrast.bitmap:=bm
  366.                 IF usehighpen=256 THEN usehighpen:=-1
  367.                 IF bm<>NIL
  368.                     body:=cregs
  369.                     FOR i:=0 TO (Shl(1,(bmhd.depth))-1)
  370.                         ditz:=body[0];body:=body+4;red[i]:=ditz
  371.                         dang:=body[0];body:=body+4;grn[i]:=dang
  372.                         dumb:=body[0];body:=body+4;blu[i]:=dumb
  373.                     ENDFOR
  374.                     grabbuf:=New(128)
  375.  
  376.                     tbm:=AllocBitMap((bmhd.width*2),1,8,(BMF_CLEAR OR BMF_STANDARD),NIL)
  377.                     trast.bitmap:=tbm
  378.  
  379.                     adjustw:=SpFlt(bmhd.width)
  380.                     adjusth:=SpFlt(bmhd.height)
  381.                     IF ((useaspect<>FALSE) AND (intscale=FALSE))
  382.                         IF bmhd.xaspect=0 THEN bmhd.xaspect:=1
  383.                         IF bmhd.yaspect=0 THEN bmhd.yaspect:=1
  384.                         scalarx:=SpDiv(SpFlt(aspectx),SpFlt(bmhd.xaspect))
  385.                         scalary:=SpDiv(SpFlt(aspecty),SpFlt(bmhd.yaspect))
  386.  
  387.                         res:=SpCmp(scalarx,scalary)
  388.                         IF res<0    -> scaraly is GREATER THAN scalarx
  389.                             percent:=SpDiv(scalarx,scalary)
  390.                             adjusth:=SpMul(percent,SpFlt(bmhd.height))
  391.                         ELSE
  392.                             percent:=SpDiv(scalary,scalarx)
  393.                             adjustw:=SpMul(percent,SpFlt(bmhd.width))
  394.                         ENDIF
  395.                     ENDIF
  396.  
  397.                     finalx:=x;finaly:=y;finalw:=w;finalh:=h;scalex:=SpFlt(1);scaley:=SpFlt(1)
  398.  
  399.                     res:=SpCmp(SpFlt(w),adjustw)
  400.                     res2:=SpCmp(SpFlt(h),adjusth)
  401.                     IF (((res<0) OR (res2<0)) AND (scale<>FALSE))    -> Datatype is LARGER than workspace, so scale?
  402.                         IF (intscale<>FALSE)
  403.                             scalex:=SpFlt(SpFix( SpDiv(SpFlt(w),SpFlt(SpFix(adjustw)))))
  404.                             scaley:=SpFlt(SpFix( SpDiv(SpFlt(h),SpFlt(SpFix(adjusth)))))
  405.                             res:=SpCmp(scalex,scaley)
  406.                             IF (res<0);scalef:=scaley;ELSE;scalef:=scalex;ENDIF
  407.                             finalw:=SpFix(SpDiv(scalef,adjustw))
  408.                             finalh:=SpFix(SpDiv(scalef,adjusth))
  409.                         ELSE
  410.                             scalex:=SpDiv(SpFlt(w),adjustw)
  411.                             scaley:=SpDiv(SpFlt(h),adjusth)
  412.                             res:=SpCmp(scalex,scaley)
  413.                             IF (res<0);scalef:=scaley;ELSE;scalef:=scalex;ENDIF
  414.                             finalw:=SpFix(SpDiv(scalef,adjustw))
  415.                             finalh:=SpFix(SpDiv(scalef,adjusth))
  416.                         ENDIF
  417.                         IF (stretch)
  418.                             finalw:=smaller(bmhd.width,w);finalh:=smaller(bmhd.height,h)
  419. ->                            finalw:=w;finalh:=h
  420.                         ENDIF
  421.                         xpixper:=SpDiv(SpFlt(finalw),SpFlt(bmhd.width))
  422.                         ypixper:=SpDiv(SpFlt(finalh),SpFlt(bmhd.height))
  423.                     ELSE
  424.                         finalw:=smaller(bmhd.width,w);finalh:=smaller(bmhd.height,h)
  425.                         xpixper:=SpFlt(1);ypixper:=SpFlt(1)
  426.                     ENDIF
  427.  
  428. ->WriteF('\nfinalw=\d\nfinalh=\d\nxpixper=\d\nypixper=\d\n',finalw,finalh,SpFix(xpixper),SpFix(ypixper))
  429.                     
  430.                     IF center
  431.                         finalx:=x+(w/2)-(finalw/2)
  432.                         finaly:=y+(h/2)-(finalh/2)
  433.                     ENDIF
  434.  
  435.                     IF statgad THEN enablegadget(statgad,statwindow)
  436.  
  437.                     IF ((remap=FALSE) AND (scale=FALSE))
  438.                         FOR t:=0 TO finalh-1
  439.                             IF checkcancel(statwindow) THEN Raise("canc")
  440.                             IF (((t+3)/4) = (t/4))
  441.                                 IF gaugeobj THEN fuelgauge(statwindow.rport,gaugeobj,t,finalh-1,stat.render_string,drawinfo)
  442.                             ENDIF
  443.                             FOR i:=0 TO finalw-1
  444.                                 fc:=ReadPixel(dtrast,i,t)
  445.                                 WHILE fc>usehighpen
  446.                                     fc:=Shr(fc,1)
  447.                                 ENDWHILE
  448.                                 IF highpen<fc THEN highpen:=fc
  449.                                 SetAPen(rast,fc)
  450.                                 WritePixel(rast,finalx+i,finaly+t)
  451.                             ENDFOR
  452.                         ENDFOR
  453.                     ELSE
  454.                         redbuf:=New(bmhd.width*(SpFix(ypixper)*4)*2)
  455.                         grnbuf:=New(bmhd.width*(SpFix(ypixper)*4)*2)
  456.                         blubuf:=New(bmhd.width*(SpFix(ypixper)*4)*2)
  457.                         linebuf:=New(bmhd.width*8)
  458.  
  459.                         sfixx:=SpFix(xpixper)-1
  460.                         sfixy:=SpFix(ypixper)-1
  461.  
  462.                         red24:=New(finalw*(finalh+16))
  463.                         grn24:=New(finalw*(finalh+16))
  464.                         blu24:=New(finalw*(finalh+16))
  465.  
  466.                         FOR t:=0 TO (finalh-1)
  467.                             IF checkcancel(statwindow) THEN Raise("canc")
  468.                             IF (((t+3)/4) = (t/4))
  469.                                 IF gaugeobj THEN fuelgauge(statwindow.rport,gaugeobj,t,finalh-1,stat.scale_string,drawinfo)
  470.                             ENDIF
  471.  
  472.                             FOR u:=t TO t+SpFix(ypixper)-1
  473.                                 ReadPixelLine8(dtrast,0,SpFix(SpMul(SpFlt(t),ypixper))+(u-t),bmhd.width,linebuf,trast)
  474.                                 speed8:=linebuf[0]
  475.                                 tmp1:=red[speed8];tmp2:=grn[speed8];tmp3:=blu[speed8]
  476.                                 IF (hammode)
  477.                                     tmp1:=red[0];tmp2:=grn[0];tmp3:=blu[0]
  478.                                     IF bmhd.depth=8    -> HAM8
  479.                                         IF (speed8 AND %11000000)
  480.                                             IF ((speed8 AND %11000000)=%10000000)    -> Modify RED
  481.                                                 tmp1:=Shl((speed8 AND %111111),2);ENDIF
  482.                                             IF ((speed8 AND %11000000)=%01000000)    -> Modify BLUE
  483.                                                 tmp3:=Shl((speed8 AND %111111),2);ENDIF
  484.                                             IF ((speed8 AND %11000000)=%11000000)    -> Modify GRN
  485.                                                 tmp2:=Shl((speed8 AND %111111),2);ENDIF
  486.                                         ELSE
  487.                                             tmp1:=red[(speed8 AND %111111)];tmp2:=grn[(speed8 AND %111111)];tmp3:=blu[(speed8 AND %111111)]
  488.                                         ENDIF
  489.                                     ELSE
  490.                                         IF (speed8 AND %110000)
  491.                                             IF (speed8 AND %110000)=%100000    -> Modify RED
  492.                                                 tmp1:=Shl((speed8 AND %1111),4);ENDIF
  493.                                             IF (speed8 AND %110000)=%010000    -> Modify BLUE
  494.                                                 tmp3:=Shl((speed8 AND %1111),4);ENDIF
  495.                                             IF (speed8 AND %110000)=%110000    -> Modify GRN
  496.                                                 tmp2:=Shl((speed8 AND %1111),4);ENDIF
  497.                                         ELSE
  498.                                             tmp1:=red[(z AND %1111)];tmp2:=grn[(z AND %1111)];tmp3:=blu[(z AND %1111)]
  499.                                         ENDIF
  500.                                     ENDIF
  501.                                 ENDIF
  502.                                 speed1:=bmhd.width*(u-t)
  503.                                 ditz:=redbuf+speed1
  504.                                 dang:=grnbuf+speed1
  505.                                 dumb:=blubuf+speed1
  506.                                 IF (remap=FALSE) THEN ditz:=redbuf
  507.                                 FOR v:=1 TO bmhd.width
  508.                                     IF (remap=FALSE)
  509.                                         ditz[0]:=linebuf[v];ditz:=ditz+1
  510.                                     ELSE
  511.  
  512. /*                                        MOVE.L    tmp1,D0
  513.                                         MOVE.L    tmp2,D1
  514.                                         MOVE.L    tmp3,D2
  515.  
  516.                                         LEA            ditz,A1
  517.                                         MOVE.L    (A1),A0
  518.                                         MOVE.B    D0,(A0)+
  519.                                         MOVE.L    A0,(A1)
  520.  
  521.                                         LEA            dang,A1
  522.                                         MOVE.L    (A1),A0
  523.                                         MOVE.B    D1,(A0)+
  524.                                         MOVE.L    A0,(A1)
  525.  
  526.                                         LEA            dumb,A1
  527.                                         MOVE.L    (A1),A0
  528.                                         MOVE.B    D2,(A0)+
  529.                                         MOVE.L    A0,(A1)
  530. */
  531.  
  532.                                         ditz[0]:=tmp1;ditz:=ditz+1
  533.                                         dang[0]:=tmp2;dang:=dang+1
  534.                                         dumb[0]:=tmp3;dumb:=dumb+1
  535.  
  536. /*
  537.                                         MOVE.L    linebuf,A0
  538.                                         MOVE.L    v,D0
  539.                                         SUB.L        D1,D1
  540.                                         MOVE.B    0(A0,D0),D1
  541.                                         MOVE.L    D1,z
  542. */
  543.                                         z:=linebuf[v]
  544.  
  545.                                         IF (hammode=FALSE)
  546.                                             tmp1:=red[z];tmp2:=grn[z];tmp3:=blu[z]
  547.                                         ELSE
  548.                                             IF (bmhd.depth=8)    -> HAM8
  549.                                                 speed7:=(z AND %11000000)
  550.                                                 IF (speed7)
  551.                                                     IF (speed7=%10000000)    -> Modify RED
  552.                                                         tmp1:=Shl((z AND %111111),2)
  553.                                                     ELSE
  554.                                                         IF (speed7=%01000000)
  555.                                                             tmp3:=Shl((z AND %111111),2)
  556.                                                         ELSE
  557.                                                             tmp2:=Shl((z AND %111111),2)
  558.                                                         ENDIF
  559.                                                     ENDIF
  560.                                                 ELSE
  561.                                                     speed6:=(z AND %111111)
  562.                                                     tmp1:=red[speed6];tmp2:=grn[speed6];tmp3:=blu[speed6]
  563.                                                 ENDIF
  564.                                             ELSE
  565.                                                 IF (z AND %110000)
  566.                                                     IF (z AND %110000)=%100000    -> Modify RED
  567.                                                         tmp1:=Shl((z AND %1111),4);ENDIF
  568.                                                     IF (z AND %110000)=%010000    -> Modify BLUE
  569.                                                         tmp3:=Shl((z AND %1111),4);ENDIF
  570.                                                     IF (z AND %110000)=%110000    -> Modify GRN
  571.                                                         tmp2:=Shl((z AND %1111),4);ENDIF
  572.                                                 ELSE
  573.                                                     speed6:=(z AND %1111)
  574.                                                     tmp1:=red[speed6];tmp2:=grn[speed6];tmp3:=blu[speed6]
  575.                                                 ENDIF
  576.                                             ENDIF
  577.                                         ENDIF
  578.                                     ENDIF
  579.                                 ENDFOR
  580.                             ENDFOR
  581.                             IF (remap=FALSE)
  582.                                 FOR i:=0 TO finalw-1
  583.                                     fc:=Char(redbuf+(SpFix(SpMul(xpixper,SpFlt(i)))))
  584.                                     SetAPen(rast,fc)
  585.                                     highpen:=bigger(highpen,fc)
  586.                                      WritePixel(rast,finalx+i,finaly+t)
  587.                                  ENDFOR
  588.                             ELSE
  589.                                 FOR i:=0 TO finalw-1
  590.                                     tmp4:=(SpFix(SpMul(xpixper,SpFlt(i))))
  591.                                     ditz:=redbuf+tmp4
  592.                                     dang:=grnbuf+tmp4
  593.                                     dumb:=blubuf+tmp4
  594.                                     IF ((sfixy>=1) AND (sfixx>=1))
  595.                                         num:=0;sumred:=0;sumgrn:=0;sumblu:=0
  596.                                         MOVEM.L    D0-D7/A0-A3,-(A7)
  597.                                          MOVE.L    ditz,A0
  598.                                          MOVE.L    dang,A1
  599.                                         MOVE.L    dumb,A2
  600.                                         MOVE.L    bmhd,A3
  601.                                         CLR.L        D2        -> The result from Char()
  602.                                         CLR.L        D4        -> num
  603.                                         CLR.L        D5        -> sumred
  604.                                         CLR.L        D6        -> sumgrn
  605.                                         CLR.L        D7        -> sumblu
  606.                                         MOVE.L    sfixy,D0
  607. ->                                        ADD.L        #1,D0
  608. loop3:
  609.                                         MOVE.L    sfixx,D1
  610. ->                                         ADD.L        #1,D1
  611. loop2:
  612.                                         SUB.L        D3,D3                -> EQ: CLR.L    D3 ? Is it faster??!?
  613.                                         MOVE.W    0(A3),D3
  614.                                         MULU        D0,D3
  615.                                         ADD.L        D1,D3
  616.                                         MOVE.B    0(A0,D3),D2
  617.                                         ADD.L        D2,D5
  618.                                         MOVE.B    0(A1,D3),D2
  619.                                         ADD.L        D2,D6
  620.                                         MOVE.B    0(A2,D3),D2
  621.                                         ADD.L        D2,D7
  622.                                         ADDQ.L    #1,D4
  623.                                         DBRA        D1,loop2
  624.                                         DBRA        D0,loop3
  625.                                         MOVE.L    D4,num
  626.                                         MOVE.L    D5,sumred
  627.                                         MOVE.L    D6,sumgrn
  628.                                         MOVE.L    D7,sumblu
  629.                                         MOVEM.L    (A7)+,D0-D7/A0-A3
  630.                                         IF num>0
  631.                                              sumred:=limit(sumred/num,0,255)
  632.                                              sumgrn:=limit(sumgrn/num,0,255)
  633.                                              sumblu:=limit(sumblu/num,0,255)
  634.                                         ENDIF
  635.                                     ELSE
  636.                                          sumred:=ditz[0]
  637.                                          sumgrn:=dang[0]
  638.                                          sumblu:=dumb[0]
  639.                                     ENDIF
  640.                                     MOVE.L    t,D1
  641.                                     MOVE.L    finalw,D2
  642.                                     MULU        D2,D1
  643.                                     ADD.L        i,D1
  644.  
  645.                                     MOVE.L    D1,D0
  646.                                     ADD.L        red24,D0
  647.                                     MOVE.L    D0,A0
  648.                                     MOVE.L    sumred,D2
  649.                                     MOVE.B    D2,(A0)
  650.                                     
  651.                                     MOVE.L    D1,D0
  652.                                     ADD.L        grn24,D0
  653.                                     MOVE.L    D0,A0
  654.                                     MOVE.L    sumgrn,D2
  655.                                     MOVE.B    D2,(A0)
  656.                                     
  657.                                     MOVE.L    D1,D0
  658.                                     ADD.L        blu24,D0
  659.                                     MOVE.L    D0,A0
  660.                                     MOVE.L    sumblu,D2
  661.                                     MOVE.B    D2,(A0)
  662.                                     
  663.                                 ENDFOR
  664.                             ENDIF
  665.                         ENDFOR
  666.                         IF showsize THEN mergesize(showsize,bmhd.width,bmhd.height,red24,grn24,blu24,finalw,finalh)
  667.                         IF grey
  668.                             tmp1:=red24
  669.                             tmp2:=grn24
  670.                             tmp3:=blu24
  671.                             tmp7:=finalh*finalw-1
  672.                             FOR i:=0 TO tmp7
  673.                                 IF grey=1
  674.                                     er1:=(tmp1[0]*1000)/30
  675.                                     er2:=(tmp2[0]*1000)/30
  676.                                     er3:=(tmp3[0]*1000)/30
  677.                                 ELSE
  678.                                     er1:=(tmp1[0]*3000)/100
  679.                                     er2:=(tmp2[0]*6000)/100
  680.                                     er3:=(tmp3[0]*1000)/100
  681.                                 ENDIF
  682.                                 er4:=(er1+er2+er3)/100
  683.                                 tmp1[0]:=er4
  684.                                 tmp2[0]:=er4
  685.                                 tmp3[0]:=er4
  686.                                 tmp1:=tmp1+1
  687.                                 tmp2:=tmp2+1
  688.                                 tmp3:=tmp3+1
  689.                             ENDFOR
  690.                         ENDIF
  691.  
  692.                         IF (fillcmap)
  693.                             IF usehighpen>=quant THEN usehighpen:=(quant-1)
  694.                             SELECT QUANT_END OF quantmode
  695.                             CASE QUANT_VERBATIM
  696.                                 FOR i:=0 TO quant
  697.                                     SetRGB32CM(cmap,smaller(i,255),byte2long(red[i]),byte2long(grn[i]),byte2long(blu[i]))
  698.                                 ENDFOR
  699.                             CASE QUANT_POPULARITY
  700.                                 histo:=New(20000)
  701.                                 FOR t:=0 TO finalh-1
  702.                                     IF checkcancel(statwindow) THEN Raise("canc")
  703.                                         IF ((t/4)=((t+3)/4))
  704.                                             IF gaugeobj THEN fuelgauge(statwindow.rport,gaugeobj,t,finalh-1,stat.histogram_string,drawinfo)
  705.                                         ENDIF
  706.                                     FOR i:=0 TO finalw-1
  707.                                         tmp1:=Shr((Char(red24+(t*finalw)+i) AND $F0) ,4)
  708.                                         tmp2:=Shr((Char(grn24+(t*finalw)+i) AND $F0) ,4)
  709.                                         tmp3:=Shr((Char(blu24+(t*finalw)+i) AND $F0) ,4)
  710.                                         tmp4:=histo+((tmp1+(tmp2*16)+(tmp3*256))*4)
  711.                                         tmp4[0]:=tmp4[0]+1
  712.                                     ENDFOR
  713.                                 ENDFOR
  714.                                 FOR i:=0 TO quant
  715.                                     IF checkcancel(statwindow) THEN Raise("canc")
  716.                                         IF gaugeobj THEN fuelgauge(statwindow.rport,gaugeobj,i,quant,stat.quant_string,drawinfo)
  717.                                     tmp1:=0
  718.                                     tmp2:=0
  719.                                     longptr:=histo
  720.                                     FOR t:=0 TO 4095
  721.                                         IF longptr[0]>tmp2
  722.                                             tmp2:=longptr[0]
  723.                                             tmp1:=t
  724.                                         ENDIF
  725.                                         longptr:=longptr+4
  726.                                     ENDFOR
  727.                                     histo[tmp1]:=0
  728.                                     er1:=tmp1 AND $F
  729.                                     er1:=er1 OR Shl(er1,4)
  730.                                     er2:=Shr((tmp1 AND $F0),4)
  731.                                     er2:=er2 OR Shl(er2,4)
  732.                                     er3:=Shr((tmp1 AND $F00),8)
  733.                                     er3:=er3 OR Shl(er3,4)
  734.                                     SetRGB32CM(cmap,smaller(i,255),byte2long(er1),byte2long(er2),byte2long(er3))
  735.                                 ENDFOR
  736.                             DEFAULT
  737.                                 cm:=domediancut(red24,grn24,blu24,finalw,finalh,cmap,quant,quantmode)
  738.                                 IF (cm)
  739.                                     FOR i:=0 TO (quant)
  740.                                         SetRGB32CM(cmap,smaller(i,255),byte2long(PPM_GETR(Long(cm+(i*SIZEOF colorhist_item)))),byte2long(PPM_GETG(Long(cm+(i*SIZEOF colorhist_item)))),byte2long(PPM_GETB(Long(cm+(i*SIZEOF colorhist_item)))))
  741.                                     ENDFOR
  742.                                     Dispose(cm)
  743.                                 ENDIF
  744.                             ENDSELECT
  745.                             IF ((quant>4) AND (quantmode<>QUANT_VERBATIM))
  746.                                 doexchange(cmap,3,0,255,255,usehighpen)
  747.                                 doexchange(cmap,2,255,255,255,usehighpen)
  748.                                 doexchange(cmap,1,0,0,0,usehighpen)
  749.                                 doexchange(cmap,0,128,128,128,usehighpen)
  750.                                 REPEAT
  751.                                     tmp1:=0
  752.                                     FOR i:=4 TO (quant-1)
  753.                                         GetRGB32(cmap,i,2,grabbuf)
  754.                                         IF ((grabbuf[0]+grabbuf[4]+grabbuf[8])<(grabbuf[12]+grabbuf[16]+grabbuf[20]))
  755.                                             SetRGB32CM(cmap,smaller(i+1,255),byte2long(grabbuf[0]),byte2long(grabbuf[4]),byte2long(grabbuf[8]))
  756.                                             SetRGB32CM(cmap,smaller(i,255),byte2long(grabbuf[12]),byte2long(grabbuf[16]),byte2long(grabbuf[20]))
  757.                                             tmp1:=1
  758.                                         ENDIF
  759.                                     ENDFOR
  760.                                 UNTIL tmp1=0
  761.                             ENDIF
  762.                         ENDIF
  763.                         IF (norender) THEN Raise("nore")
  764.                         IF (clear<>FALSE);SetAPen(rast,0);RectFill(rast,x,y,x+w-1,y+h-1);ENDIF
  765.                         FOR i:=0 TO Shl(1,8)-1
  766.                             GetRGB32(cmap,i,1,grabbuf)
  767.                             realred[i]:=grabbuf[0]
  768.                             realgrn[i]:=grabbuf[4]
  769.                             realblu[i]:=grabbuf[8]
  770.                         ENDFOR
  771.                         IF renderham THEN dither:=FALSE
  772. ->WriteF('\nfinalw=\d\nfinalh=\d\nxpixper=\d\nypixper=\d\n',finalw,finalh,SpFix(xpixper),SpFix(ypixper))
  773.                         FOR t:=0 TO finalh-1
  774.                             IF checkcancel(statwindow) THEN Raise("canc")
  775.                             IF (((t+3)/4)=(t/4))
  776.                                 IF (gaugestr<>0)
  777.                                     WriteF(gaugestr,smaller(((t*100))/(bigger(finalh-1,1)),100))
  778.                                 ENDIF
  779.                                 IF gaugeobj THEN fuelgauge(statwindow.rport,gaugeobj,t,finalh-1,stat.render_string,drawinfo)
  780.                             ENDIF
  781.  
  782.                             IF ((((t+1)/2)=(t/2)) OR (renderham>5) OR (dithermode=DITH_ERRORDIFF))
  783.                                 i:=0;stop:=finalw;step:=1
  784.                                 tmp4:=t*finalw
  785.                                 tmp1:=red24+tmp4
  786.                                 tmp2:=grn24+tmp4
  787.                                 tmp3:=blu24+tmp4
  788.                             ELSE
  789.                                 i:=finalw-1;stop:=-1;step:=-1
  790.                                 tmp4:=(t*finalw)+(finalw-1)
  791.                                 tmp1:=red24+tmp4
  792.                                 tmp2:=grn24+tmp4
  793.                                 tmp3:=blu24+tmp4
  794.                             ENDIF
  795.                             REPEAT
  796.                                 tmp4:=tmp1[0]
  797.                                 tmp5:=tmp2[0]
  798.                                 tmp6:=tmp3[0]
  799.                                 lmp4:=byte2long(tmp4)
  800.                                 lmp5:=byte2long(tmp5)
  801.                                 lmp6:=byte2long(tmp6)
  802.                                 IF (dither=FALSE)
  803.                                     SELECT 9 OF renderham
  804.                                     CASE 6,8
  805.                                         IF (i>0)
  806.                                             fc:=FindColor(cmap,lmp4,lmp5,lmp6,hambase)
  807.                                             hadr:=Abs(tmp4-realred[fc])
  808.                                             hadg:=Abs(tmp5-realgrn[fc])
  809.                                             hadb:=Abs(tmp6-realblu[fc])
  810.                                             IF ((hadr+hadg+hadb)<=hamthres)
  811.                                                 hamr:=realred[fc]            -> CHAR
  812.                                                 hamg:=realgrn[fc]
  813.                                                 hamb:=realblu[fc]
  814.                                             ELSE
  815.                                                 hadr:=Abs(tmp4-hamr)    -> CHAR-CHAR
  816.                                                 hadg:=Abs(tmp5-hamg)
  817.                                                 hadb:=Abs(tmp6-hamb)
  818.                                                 IF (renderham=8)
  819.                                                     IF ((hadb>(hadr*2)) AND (hadb>(hadg*3)))
  820.                                                         hamb:=(tmp6 AND %11111100)
  821.                                                         fc:=(%01000000 OR Shr(hamb,2))
  822.                                                         IF (discard) THEN hamb:=(tmp6 AND %11111111)
  823.                                                     ELSE
  824.                                                         IF (hadr>(hadg*2))
  825.                                                             hamr:=(tmp4 AND %11111100)
  826.                                                             fc:=(%10000000 OR Shr(hamr,2))
  827.                                                             IF (discard) THEN hamr:=(tmp4 AND %11111111)
  828.                                                         ELSE
  829.                                                             hamg:=(tmp5 AND %11111100)
  830.                                                             fc:=(%11000000 OR Shr(hamg,2))
  831.                                                             IF (discard) THEN hamg:=(tmp5 AND %11111111)
  832.                                                         ENDIF
  833.                                                     ENDIF
  834.                                                 ELSE
  835.                                                     IF ((hadb>(hadr*2)) AND (hadb>(hadg*3)))
  836.                                                         hamb:=(tmp6 AND %11110000)
  837.                                                         fc:=(%010000 OR Shr(hamb,4))
  838.                                                         IF (discard) THEN hamb:=(tmp6 AND %11111111)
  839.                                                     ELSE
  840.                                                         IF (hadr>(hadg*2))
  841.                                                             hamr:=(tmp4 AND %11110000)
  842.                                                             fc:=(%100000 OR Shr(hamr,4))
  843.                                                             IF (discard) THEN hamr:=(tmp4 AND %11111111)
  844.                                                         ELSE
  845.                                                             hamg:=(tmp5 AND %11110000)
  846.                                                             fc:=(%110000 OR Shr(hamg,4))
  847.                                                             IF (discard) THEN hamg:=(tmp5 AND %11111111)
  848.                                                         ENDIF
  849.                                                     ENDIF
  850.                                                 ENDIF
  851.                                             ENDIF
  852.                                         ELSE
  853.                                             fc:=FindColor(cmap,lmp4,lmp5,lmp6,hambase)
  854.                                             hamr:=realred[fc]
  855.                                             hamg:=realgrn[fc]
  856.                                             hamb:=realblu[fc]
  857.                                         ENDIF
  858.                                     DEFAULT
  859.                                         fc:=FindColor(cmap,lmp4,lmp5,lmp6,usehighpen)
  860.                                     ENDSELECT
  861.                                     IF fc>highpen THEN highpen:=fc
  862.                                     SetAPen(rast,fc)
  863.                                     WritePixel(rast,finalx+i,finaly+t)
  864.                                 ELSE                                                                                -> Do dither!
  865.                                     fc:=FindColor(cmap,lmp4,lmp5,lmp6,usehighpen)
  866.                                     IF fc>highpen THEN highpen:=fc
  867.                                     SetAPen(rast,fc)
  868.                                     WritePixel(rast,finalx+i,finaly+t)
  869.                          reddif:=tmp4-realred[fc]
  870.                        grndif:=tmp5-realgrn[fc]
  871.                        bludif:=tmp6-realblu[fc]
  872.                        SELECT 4 OF dithermode
  873.                        CASE DITH_FLOYD,DITH_ERRORDIFF
  874.                            IF dithermode=DITH_FLOYD
  875.                                er1:=(reddif*7)/16
  876.                                er2:=(reddif*3)/16
  877.                                er3:=(reddif*5)/16
  878.                                er4:=reddif-er1-er2-er3
  879.                                eg1:=(grndif*7)/16
  880.                                eg2:=(grndif*3)/16
  881.                                eg3:=(grndif*5)/16
  882.                                eg4:=grndif-eg1-eg2-eg3
  883.                                eb1:=(bludif*7)/16
  884.                                eb2:=(bludif*3)/16
  885.                                eb3:=(bludif*5)/16
  886.                                eb4:=bludif-eb1-eb2-eb3
  887.                            ELSE
  888.                                er1:=(reddif*3)/8 AND %11111111111111111111111111111110
  889.                                er2:=0
  890.                                er3:=er1
  891.                                er4:=reddif-er1-er3 AND %11111111111111111111111111111100
  892.                                eg1:=(grndif*3)/8 AND %11111111111111111111111111111100
  893.                                eg2:=0
  894.                                eg3:=eg1
  895.                                eg4:=grndif-eg1-eg3 AND %11111111111111111111111111111100
  896.                                eb1:=(bludif*3)/8 AND  %11111111111111111111111111111110
  897.                                eb2:=0
  898.                                eb3:=eb1
  899.                                eb4:=bludif-eb1-eb3 AND %11111111111111111111111111111100
  900.                              ENDIF
  901.                            IF step=1
  902.                                IF ((i+1)<stop)
  903.                                                 byteplace(tmp1+1,er1)
  904.                                                 byteplace(tmp2+1,eg1)
  905.                                                 byteplace(tmp3+1,eb1)
  906.                                             ENDIF
  907.                                IF t<(finalh-1)
  908.                                      IF ((i+1)<stop)
  909.                                          byteplace(tmp1+1+finalw,er4)
  910.                                          byteplace(tmp2+1+finalw,eg4)
  911.                                          byteplace(tmp3+1+finalw,eb4)
  912.                                      ENDIF
  913.                                      IF (i>0)
  914.                                                     byteplace(tmp1-1+finalw,er2)
  915.                                                     byteplace(tmp2-1+finalw,eg2)
  916.                                                     byteplace(tmp3-1+finalw,eb2)
  917.                                                 ENDIF
  918.                                      byteplace(tmp1+finalw,er3)
  919.                                      byteplace(tmp2+finalw,eg3)
  920.                                      byteplace(tmp3+finalw,eb3)
  921.                                  ENDIF
  922.                            ELSE
  923.                                IF ((i-1)>stop)
  924.                                    byteplace(tmp1-1,er1)
  925.                                    byteplace(tmp2-1,eg1)
  926.                                    byteplace(tmp3-1,eb1)
  927.                                ENDIF
  928.                                IF t<(finalh-1)
  929.                                      IF ((i-1)>stop)
  930.                                          byteplace(tmp1-1+finalw,er4)
  931.                                          byteplace(tmp2-1+finalw,eg4)
  932.                                          byteplace(tmp3-1+finalw,eb4)
  933.                                      ENDIF
  934.                                      IF (i<(finalw-1))
  935.                                          byteplace(tmp1+1+finalw,er2)
  936.                                          byteplace(tmp2+1+finalw,eg2)
  937.                                          byteplace(tmp3+1+finalw,eb2)
  938.                                      ENDIF
  939.                                      byteplace(tmp1+finalw,er3)
  940.                                      byteplace(tmp2+finalw,eg3)
  941.                                      byteplace(tmp3+finalw,eb3)
  942.                                  ENDIF
  943.                            ENDIF
  944.                        CASE DITH_BURKES,DITH_STUCKI
  945.                            IF dithermode=DITH_BURKES
  946.                                er1:=(reddif*8)/32                                ->8
  947.                                er2:=(reddif*4)/32                                ->4
  948.                                er3:=(reddif-(er1*2)-(er2*3))/2        ->2
  949.                                eg1:=(grndif*8)/32
  950.                                eg2:=(grndif*4)/32
  951.                                eg3:=(grndif-(eg1*2)-(eg2*3))/2
  952.                                eb1:=(bludif*8)/32
  953.                                eb2:=(bludif*4)/32
  954.                                eb3:=(bludif-(eb1*2)-(eb2*3))/2
  955.                              ELSE
  956.                                er1:=(reddif*8)/42                                ->8
  957.                                er2:=(reddif*4)/42                                ->4
  958.                                er3:=(reddif*2)/42                                ->2
  959.                                er4:=(reddif-(er1*2)-(er2*4)-(er3*4))/2        ->1
  960.                                eg1:=(grndif*8)/42
  961.                                eg2:=(grndif*4)/42
  962.                                eg3:=(grndif*2)/42
  963.                                eg4:=(grndif-(eg1*2)-(eg2*4)-(eg3*4))/2
  964.                                eb1:=(bludif*8)/42
  965.                                eb2:=(bludif*4)/42
  966.                                eb3:=(bludif*2)/42
  967.                                eb4:=(bludif-(eb1*2)-(eb2*4)-(eb3*4))/2
  968.                              ENDIF
  969.                            IF step=1
  970.                                IF ((i+1)<stop)
  971.                                                 byteplace(tmp1+1,er1)
  972.                                                 byteplace(tmp2+1,eg1)
  973.                                                 byteplace(tmp3+1,eb1)
  974.                                                 IF ((i+2)<stop)
  975.                                                     byteplace(tmp1+2,er2)
  976.                                                     byteplace(tmp2+2,eg2)
  977.                                                     byteplace(tmp3+2,eb2)
  978.                                                 ENDIF
  979.                                             ENDIF
  980.                                IF t<(finalh-1)
  981.                                    ttmp1:=tmp1+finalw
  982.                                    ttmp2:=tmp2+finalw
  983.                                    ttmp3:=tmp3+finalw
  984.                                      IF ((i+1)<stop)
  985.                                          byteplace(ttmp1+1,er2)
  986.                                          byteplace(ttmp2+1,eg2)
  987.                                          byteplace(ttmp3+1,eb2)
  988.                                                     IF ((i+2)<stop)
  989.                                                         byteplace(ttmp1+2,er3)
  990.                                                         byteplace(ttmp2+2,eg3)
  991.                                                         byteplace(ttmp3+2,eb3)
  992.                                                     ENDIF
  993.                                      ENDIF
  994.                                      IF (i>0)
  995.                                                     byteplace(ttmp1-1,er2)
  996.                                                     byteplace(ttmp2-1,eg2)
  997.                                                     byteplace(ttmp3-1,eb2)
  998.                                          IF (i>1)
  999.                                                         byteplace(ttmp1-2,er3)
  1000.                                                         byteplace(ttmp2-2,eg3)
  1001.                                                         byteplace(ttmp3-2,eb3)
  1002.                                          ENDIF
  1003.                                                 ENDIF
  1004.                                      byteplace(ttmp1,er1)
  1005.                                      byteplace(ttmp2,eg1)
  1006.                                      byteplace(ttmp3,eb1)
  1007.                                      IF dithermode=DITH_STUCKI
  1008.                                        IF t<(finalh-1)
  1009.                                            ttmp1:=ttmp1+finalw
  1010.                                            ttmp2:=ttmp2+finalw
  1011.                                            ttmp3:=ttmp3+finalw
  1012.                                              IF ((i+1)<stop)
  1013.                                                  byteplace(ttmp1+1,er3)
  1014.                                                  byteplace(ttmp2+1,eg3)
  1015.                                                  byteplace(ttmp3+1,eb3)
  1016.                                                             IF ((i+2)<stop)
  1017.                                                                 byteplace(ttmp1+2,er4)
  1018.                                                                 byteplace(ttmp2+2,eg4)
  1019.                                                                 byteplace(ttmp3+2,eb4)
  1020.                                                             ENDIF
  1021.                                              ENDIF
  1022.                                              IF (i>0)
  1023.                                                             byteplace(ttmp1-1,er3)
  1024.                                                             byteplace(ttmp2-1,eg3)
  1025.                                                             byteplace(ttmp3-1,eb3)
  1026.                                                  IF (i>1)
  1027.                                                                 byteplace(ttmp1-2,er4)
  1028.                                                                 byteplace(ttmp2-2,eg4)
  1029.                                                                 byteplace(ttmp3-2,eb4)
  1030.                                                  ENDIF
  1031.                                                         ENDIF
  1032.                                              byteplace(ttmp1,er2)
  1033.                                              byteplace(ttmp2,eg2)
  1034.                                              byteplace(ttmp3,eb2)
  1035.                                          ENDIF
  1036.                                      ENDIF
  1037.                                  ENDIF
  1038.                            ELSE
  1039.                                IF ((i-1)>stop)
  1040.                                                 byteplace(tmp1-1,er1)
  1041.                                                 byteplace(tmp2-1,eg1)
  1042.                                                 byteplace(tmp3-1,eb1)
  1043.                                                 IF ((i-2)>stop)
  1044.                                                     byteplace(tmp1-2,er2)
  1045.                                                     byteplace(tmp2-2,eg2)
  1046.                                                     byteplace(tmp3-2,eb2)
  1047.                                                 ENDIF
  1048.                                             ENDIF
  1049.                                IF t<(finalh-1)
  1050.                                    ttmp1:=tmp1+finalw
  1051.                                    ttmp2:=tmp2+finalw
  1052.                                    ttmp3:=tmp3+finalw
  1053.                                      IF ((i-1)>stop)
  1054.                                          byteplace(ttmp1-1,er2)
  1055.                                          byteplace(ttmp2-1,eg2)
  1056.                                          byteplace(ttmp3-1,eb2)
  1057.                                                     IF ((i-2)>stop)
  1058.                                                         byteplace(ttmp1-2,er3)
  1059.                                                         byteplace(ttmp2-2,eg3)
  1060.                                                         byteplace(ttmp3-2,eb3)
  1061.                                                     ENDIF
  1062.                                      ENDIF
  1063.                                      IF (i<(finalw-1))
  1064.                                                     byteplace(ttmp1+1,er2)
  1065.                                                     byteplace(ttmp2+1,eg2)
  1066.                                                     byteplace(ttmp3+1,eb2)
  1067.                                          IF (i<(finalw-2))
  1068.                                                         byteplace(ttmp1+2,er3)
  1069.                                                         byteplace(ttmp2+2,eg3)
  1070.                                                         byteplace(ttmp3+2,eb3)
  1071.                                          ENDIF
  1072.                                                 ENDIF
  1073.                                      byteplace(ttmp1,er1)
  1074.                                      byteplace(ttmp2,eg1)
  1075.                                      byteplace(ttmp3,eb1)
  1076.                                      IF dithermode=DITH_STUCKI
  1077.                                        IF (t<(finalh-1))
  1078.                                            ttmp1:=ttmp1+finalw
  1079.                                            ttmp2:=ttmp2+finalw
  1080.                                            ttmp3:=ttmp3+finalw
  1081.                                              IF ((i-1)>stop)
  1082.                                                  byteplace(ttmp1-1,er3)
  1083.                                                  byteplace(ttmp2-1,eg3)
  1084.                                                  byteplace(ttmp3-1,eb3)
  1085.                                                             IF ((i-2)>stop)
  1086.                                                                 byteplace(ttmp1-2,er4)
  1087.                                                                 byteplace(ttmp2-2,eg4)
  1088.                                                                 byteplace(ttmp3-2,eb4)
  1089.                                                             ENDIF
  1090.                                              ENDIF
  1091.                                              IF (i<(finalw-1))
  1092.                                                             byteplace(ttmp1+1,er3)
  1093.                                                             byteplace(ttmp2+1,eg3)
  1094.                                                             byteplace(ttmp3+1,eb3)
  1095.                                                  IF (i<(finalw-2))
  1096.                                                                 byteplace(ttmp1+2,er4)
  1097.                                                                 byteplace(ttmp2+2,eg4)
  1098.                                                                 byteplace(ttmp3+2,eb4)
  1099.                                                  ENDIF
  1100.                                                         ENDIF
  1101.                                              byteplace(ttmp1,er2)
  1102.                                              byteplace(ttmp2,eg2)
  1103.                                              byteplace(ttmp3,eb2)
  1104.                                          ENDIF
  1105.                                      ENDIF
  1106.                                  ENDIF
  1107.                            ENDIF
  1108.                                     ENDSELECT
  1109.                                 ENDIF
  1110.                                 tmp1:=tmp1+step
  1111.                                 tmp2:=tmp2+step
  1112.                                 tmp3:=tmp3+step
  1113.                             i:=i+step;UNTIL i=stop
  1114.                         ENDFOR
  1115.                     ENDIF
  1116.                     IF (renderham=6) THEN highpen:=63
  1117.                     IF (renderham=8) THEN highpen:=255
  1118.                     IF iinfo
  1119.                         iinfo.source_w:=bmhd.width
  1120.                         iinfo.source_h:=bmhd.height
  1121.                         iinfo.destination_x:=finalx
  1122.                         iinfo.destination_y:=finaly
  1123.                         iinfo.destination_w:=finalw
  1124.                         iinfo.destination_h:=finalh
  1125.                         iinfo.depth:=bmhd.depth
  1126.                         iinfo.highest_pen:=highpen
  1127.                         IF ((renderham=6) OR (renderham=8)) THEN usehighpen:=3
  1128.                         iinfo.blackpen:=FindColor(cmap,0,0,0,usehighpen)
  1129.                         iinfo.whitepen:=FindColor(cmap,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,usehighpen)
  1130.                         iinfo.greypen:=FindColor(cmap,$99999999,$99999999,$99999999,usehighpen)
  1131.                         IF statwindow
  1132.                             iinfo.statwindowx:=stat.centerx-(statx-statwindow.leftedge)
  1133.                             iinfo.statwindowy:=stat.centery-(staty-statwindow.topedge)
  1134.                         ENDIF
  1135.                     ENDIF
  1136.                     IF (gaugestr<>0)
  1137.                         WriteF(gaugestr,100)
  1138.                     ENDIF
  1139.                 ELSE
  1140.                     Raise("MEM")
  1141.                 ENDIF
  1142.             ELSE
  1143.                 Raise("Nodt")
  1144.             ENDIF
  1145.         ELSE
  1146.             Raise("Nodt")
  1147.         ENDIF
  1148.     ELSE
  1149.         Raise("Nodt")
  1150.     ENDIF
  1151. EXCEPT DO
  1152.     res:=exception
  1153.     IF statwindow
  1154.         CloseWindow(statwindow)
  1155.         IF glist
  1156.             FreeGadgets(glist)
  1157.         ENDIF
  1158.         statwindow:=0
  1159.     ENDIF
  1160.     IF gaugeobj THEN DisposeObject(gaugeobj)
  1161.     IF vis THEN FreeVisualInfo(vis)
  1162.     IF obj THEN DisposeDTObject(obj)
  1163.     IF tbm THEN FreeBitMap(tbm)
  1164.     IF redbuf THEN Dispose(redbuf)
  1165.     IF grnbuf THEN Dispose(grnbuf)
  1166.     IF blubuf THEN Dispose(blubuf)
  1167.     IF linebuf THEN Dispose(linebuf)
  1168.     IF grabbuf THEN Dispose(grabbuf)
  1169.     IF trast THEN Dispose(trast)
  1170.     IF dtf THEN Dispose(dtf)
  1171.     IF fri THEN Dispose(fri)
  1172.     IF histo THEN Dispose(histo)
  1173.     IF red24 THEN Dispose(red24)
  1174.     IF grn24 THEN Dispose(grn24)
  1175.     IF blu24 THEN Dispose(blu24)
  1176.     IF gpl THEN Dispose(gpl)
  1177.     IF dtrast THEN Dispose(dtrast)
  1178.     IF gaugeclass THEN Free_gaugeiclass(gaugeclass)
  1179. ENDPROC res
  1180.  
  1181. PROC checklibs()
  1182.     IF ((iffparsebase<>0) AND (utilitybase<>0) AND (datatypesbase<>0) AND (mathbase<>0) AND (gaugeimagebase<>0)) THEN RETURN TRUE
  1183. ENDPROC FALSE        
  1184.  
  1185. PROC checkcancel(window:PTR TO window)
  1186.     DEF mes:PTR TO intuimessage
  1187.     DEF    class
  1188.     DEF retu=FALSE
  1189.     IF window
  1190.         REPEAT
  1191.             IF mes:=Gt_GetIMsg(window.userport)
  1192.                 class:=extractmessage(mes)
  1193.                 IF (class=IDCMP_GADGETUP)
  1194.                     retu:=TRUE
  1195.                 ELSEIF class=IDCMP_REFRESHWINDOW
  1196.                     Gt_BeginRefresh(window)
  1197.                     Gt_EndRefresh(window,TRUE)
  1198.                 ENDIF
  1199.                 Gt_ReplyIMsg(mes)
  1200.             ENDIF
  1201.         UNTIL mes=0
  1202.     ELSE
  1203.         IF CtrlC() THEN retu:=TRUE
  1204.     ENDIF
  1205. ENDPROC retu
  1206.  
  1207. PROC byteplace(loc:PTR TO CHAR,error)
  1208.     DEF old
  1209.     old:=loc[0]
  1210.     old:=old+error
  1211.     IF old<0 THEN old:=0
  1212.     IF old>255 THEN old:=255
  1213.     loc[0]:=old
  1214. ENDPROC
  1215.  
  1216. /*PROC rgbint(intval)
  1217.     DEF r,g,b
  1218.     r:=intval AND $F
  1219.     r:=r OR Shl(r,4)
  1220.     g:=Shr((intval AND $F0),4)
  1221.     g:=g OR Shl(g,4)
  1222.     b:=Shr((intval AND $F00),8)
  1223.     b:=b OR Shl(b,4)
  1224. ENDPROC r,g,b*/
  1225.  
  1226. /*PROC rgb2int(r,g,b)
  1227.     DEF int=0
  1228.     int:=(Shr(r,4) OR (Shl(Shr(g,4),4)) OR (Shl(Shr(b,4),8)) )
  1229. ENDPROC int*/
  1230.  
  1231. /*PROC rgbtab(r,g,b)
  1232.     DEF rr
  1233.     rr:=(r+(g*16)+(b*256))*4
  1234. ENDPROC rr*/
  1235.  
  1236. PROC domediancut(redbuf,grnbuf,blubuf,width,height,palette,newcolors,mode=QUANT_MEDIANCUT)
  1237.     DEF chv=0:PTR TO colorhist_item
  1238.     DEF colors=0
  1239.     DEF colormap
  1240.     
  1241.     histopool:=createpool()
  1242.     chv:=computecolorhist(redbuf,grnbuf,blubuf,width,height,MAXCOLORS,{colors})
  1243.     IF chv
  1244. ->        WriteF('\n\nFOUND \d COLORS! -- Choosing \d colors...\n\n',colors,newcolors)
  1245.  
  1246.         colormap:=mediancut(chv,colors,width*height,newcolors,mode)
  1247.         
  1248.         Dispose(chv)
  1249.     ENDIF
  1250. ENDPROC colormap
  1251.  
  1252. PROC mediancut(chv,colors,sum,newcolors,mode=QUANT_MEDIANCUT)
  1253.     DEF colormap=0,bv=0
  1254.     DEF boxes,bi,i,i2,realsplit,bigbox,movebox,tmp1,tmp2,score
  1255.     DEF box:PTR TO box,chi:PTR TO colorhist_item
  1256.     DEF indx,clrs,sm,v,halfcolor,halfsum,lowersum
  1257.     DEF r,g,b,rsum,gsum,bsum
  1258.     DEF rl,gl,bl
  1259.     DEF f_0_299,f_0_587,f_0_114
  1260.     DEF colo
  1261.     bv:=New((SIZEOF box*newcolors)+100)
  1262.     f_0_299:=SpDiv(SpFlt(1000),SpFlt(299))
  1263.     f_0_587:=SpDiv(SpFlt(1000),SpFlt(587))
  1264.     f_0_114:=SpDiv(SpFlt(1000),SpFlt(114))
  1265.     IF (bv)
  1266.         colormap:=New((SIZEOF colorhist_item*newcolors)+100)
  1267.         IF (colormap)
  1268.             FOR i:=0 TO (newcolors-1)
  1269.                 PutLong(colormap+(i*SIZEOF colorhist_item),0)
  1270.                 PutLong(colormap+(i*SIZEOF colorhist_item)+4,0)
  1271.             ENDFOR
  1272.             box:=bv
  1273.             box.ind:=0
  1274.             box.colors:=colors
  1275.             box.sum:=sum
  1276.             boxes:=1
  1277.             sizebox(box,chv)
  1278.             WHILE (boxes<newcolors)
  1279.  
  1280.                 IF checkcancel(statwindow)
  1281.                     IF chv THEN Dispose(chv)
  1282.                     IF bv THEN Dispose(bv)
  1283.                     IF colormap THEN Dispose(colormap)
  1284.                     Raise("canc")
  1285.                 ENDIF
  1286.                 IF gaugeobj THEN fuelgauge(statwindow.rport,gaugeobj,boxes,newcolors,stat.quant_string,drawinfo)
  1287.  
  1288.                 FOR bi:=0 TO (boxes-1)
  1289.                     box:=bv+(bi*SIZEOF box)
  1290.                     IF box.colors>=2 THEN JUMP break2
  1291.                 ENDFOR
  1292.                 JUMP break3
  1293. break2:
  1294.                 indx:=box.ind
  1295.                 clrs:=box.colors
  1296.                 sm:=box.sum
  1297.  
  1298.                 SELECT QUANT_END OF mode
  1299. /*
  1300.                 CASE QUANT_MEDIANCUT
  1301.                     rl:=SpMul(SpFlt(box.redw),f_0_299)
  1302.                     gl:=SpMul(SpFlt(box.grnw),f_0_587)
  1303.                     bl:=SpMul(SpFlt(box.bluw),f_0_114)
  1304. */
  1305.                 CASE QUANT_MEDIANCUT4,QUANT_MEDIANCUT2,QUANT_MEDIANCUT3
  1306.                     rl:=SpFlt(box.redw)
  1307.                     gl:=SpFlt(box.grnw)
  1308.                     bl:=SpFlt(box.bluw)
  1309.                 DEFAULT
  1310.                     rl:=SpMul(SpFlt(18),SpFlt(box.redw))
  1311.                     gl:=SpMul(SpFlt(20),SpFlt(box.grnw))
  1312.                     bl:=SpMul(SpFlt(17),SpFlt(box.bluw))
  1313.                 ENDSELECT
  1314.  
  1315.                 IF ((SpCmp(gl,rl)>=0) AND (SpCmp(gl,bl)>=0))
  1316.                     qsort(chv+(indx*SIZEOF colorhist_item),0,clrs-1,$FF00)
  1317.                     v:=1
  1318.                 ELSE
  1319.                     IF (SpCmp(rl,bl)>=0)
  1320.                         qsort(chv+(indx*SIZEOF colorhist_item),0,clrs-1,$FF0000)
  1321.                         v:=0
  1322.                     ELSE
  1323.                         qsort(chv+(indx*SIZEOF colorhist_item),0,clrs-1,$FF)
  1324.                         v:=2
  1325.                     ENDIF
  1326.                 ENDIF
  1327.                 chi:=chv+(indx*SIZEOF colorhist_item)
  1328.                 lowersum:=chi.value
  1329.                 halfsum:=(sm/2)
  1330.                 i:=1
  1331.                 WHILE (i<(clrs-1))
  1332.                     IF (lowersum>=halfsum)
  1333.                         SELECT v
  1334.                         CASE 0
  1335.                             gsum:=PPM_GETR(chi.color)
  1336.                             IF gsum>rsum THEN JUMP break4
  1337.                         CASE 1
  1338.                             gsum:=PPM_GETG(chi.color)
  1339.                             IF gsum>rsum THEN JUMP break4
  1340.                         CASE 2
  1341.                             gsum:=PPM_GETB(chi.color)
  1342.                             IF gsum>rsum THEN JUMP break4
  1343.                         ENDSELECT
  1344.                     ENDIF
  1345.                     chi:=chv+((indx+i)*SIZEOF colorhist_item)
  1346.                     IF (lowersum<halfsum)
  1347.                         SELECT v
  1348.                         CASE 0;rsum:=PPM_GETR(chi.color)
  1349.                         CASE 1;rsum:=PPM_GETG(chi.color)
  1350.                         CASE 2;rsum:=PPM_GETB(chi.color)
  1351.                         ENDSELECT
  1352.                     ENDIF
  1353.                     lowersum:=lowersum+(chi.value)
  1354.                 i:=i+1;ENDWHILE
  1355.  
  1356. ->WriteF('\n\nOUCH! GOT ALL COLORS!')
  1357.  
  1358. break4:
  1359.  
  1360.                 i2:=1
  1361.                 WHILE (i2<(clrs-1))
  1362.                     SELECT v
  1363.                     CASE 0;IF (PPM_GETR(chi.color)>(box.red0+(box.redw/2))) THEN JUMP break8
  1364.                     CASE 1;IF (PPM_GETG(chi.color)>(box.grn0+(box.grnw/2))) THEN JUMP break8
  1365.                     CASE 2;IF (PPM_GETB(chi.color)>(box.blu0+(box.bluw/2))) THEN JUMP break8
  1366.                     ENDSELECT            
  1367.                     chi:=chv+((indx+i)*SIZEOF colorhist_item)
  1368.                 i2:=i2+1;ENDWHILE
  1369.  
  1370. ->WriteF('\n\nOUCH! GOT ALL COLORS!')
  1371.  
  1372. break8:
  1373.  
  1374.                 SELECT QUANT_END OF mode
  1375.                 CASE QUANT_MEDIANCUT;realsplit:=i
  1376.                 CASE QUANT_MEDIANCUT5;realsplit:=i2
  1377.                 DEFAULT;realsplit:=limit((i+i2)/2,1,(clrs-1))
  1378.                 ENDSELECT
  1379. ->WriteF('\nSplit at \d AND \d,  really at \d',i,i2,realsplit)
  1380.  
  1381.                 lowersum:=0
  1382.                 FOR i:=0 TO realsplit
  1383.                     chi:=chv+((indx+i)*SIZEOF colorhist_item)
  1384.                     lowersum:=lowersum+chi.value
  1385.                 ENDFOR
  1386.  
  1387.                 lowersum:=limit(lowersum,0,sm-1)
  1388.                 box:=bv+(bi*SIZEOF box)
  1389.                 box.colors:=realsplit
  1390.                 box.sum:=lowersum
  1391.                 sizebox(box,chv)
  1392.                 box:=bv+(boxes*SIZEOF box)
  1393.                 box.ind:=indx+realsplit
  1394.                 box.colors:=clrs-realsplit
  1395.                 box.sum:=sm-lowersum
  1396.                 sizebox(box,chv)
  1397.                 boxes:=boxes+1
  1398.  
  1399.                 bigbox:=0;movebox:=0
  1400.                 box:=(bv-SIZEOF box)
  1401.  
  1402. /*  Find the largest box to split, and move it to position ZERO. */
  1403.  
  1404.                 FOR i:=0 TO boxes-1
  1405.                     box:=(box+SIZEOF box)
  1406.                     IF (box.colors>1)
  1407.                         SELECT QUANT_END OF mode
  1408.                         CASE QUANT_MEDIANCUT
  1409.                             IF (box.redw)>bigbox
  1410.                                 bigbox:=box.redw
  1411.                                 movebox:=i
  1412.                             ENDIF
  1413.                             IF (box.grnw)>bigbox
  1414.                                 bigbox:=box.grnw
  1415.                                 movebox:=i
  1416.                             ENDIF
  1417.                             IF (box.bluw)>bigbox
  1418.                                 bigbox:=box.bluw
  1419.                                 movebox:=i
  1420.                             ENDIF
  1421.                         CASE QUANT_MEDIANCUT2
  1422.                             score:=(((box.redw*box.redw))+((box.grnw*box.grnw))+(box.bluw*box.bluw))
  1423.                             IF score>bigbox;movebox:=i;bigbox:=score;ENDIF
  1424.                         CASE QUANT_MEDIANCUT3
  1425.                             IF (boxes<(newcolors/3))
  1426.                                 IF (box.colors>bigbox);movebox:=i;bigbox:=box.colors;ENDIF
  1427.                             ELSE
  1428.                                 IF (boxes<((newcolors*2)/3))
  1429.                                     score:=((box.redw)*(box.grnw)*(box.bluw))
  1430.                                     IF (score>bigbox);movebox:=i;bigbox:=score;ENDIF
  1431.                                 ELSE
  1432.                                     IF (box.redw)>bigbox
  1433.                                         bigbox:=box.redw
  1434.                                         movebox:=i
  1435.                                     ENDIF
  1436.                                     IF (box.grnw)>bigbox
  1437.                                         bigbox:=box.grnw
  1438.                                         movebox:=i
  1439.                                     ENDIF
  1440.                                     IF (box.bluw)>bigbox
  1441.                                         bigbox:=box.bluw
  1442.                                         movebox:=i
  1443.                                     ENDIF
  1444.                                 ENDIF
  1445.                             ENDIF
  1446.                         CASE QUANT_MEDIANCUT4
  1447.                             IF (boxes*2<=newcolors)
  1448.                                 IF (box.colors>bigbox)
  1449.                                     bigbox:=box.colors
  1450.                                     movebox:=i
  1451.                                 ENDIF
  1452.                             ELSE
  1453.                                 IF (box.redw*box.grnw*box.bluw)>bigbox
  1454.                                     bigbox:=(box.redw*box.grnw*box.bluw)
  1455.                                     movebox:=i
  1456.                                 ENDIF
  1457.                             ENDIF
  1458.                         CASE QUANT_MEDIANCUT5
  1459.                             IF (((box.redw*box.colors)>bigbox))
  1460.                                 bigbox:=box.redw*box.colors
  1461.                                 movebox:=i
  1462.                             ENDIF
  1463.                             IF (((box.grnw*box.colors)>bigbox))
  1464.                                 bigbox:=box.grnw*box.colors
  1465.                                 movebox:=i
  1466.                             ENDIF
  1467.                             IF (((box.bluw*box.colors)>bigbox))
  1468.                                 bigbox:=box.bluw*box.colors
  1469.                                 movebox:=i
  1470.                             ENDIF
  1471.                         CASE QUANT_MEDIANCUT6
  1472.                             IF (((box.redw*box.colors*box.sum)>bigbox))
  1473.                                 bigbox:=box.redw*box.colors*box.sum
  1474.                                 movebox:=i
  1475.                             ENDIF
  1476.                             IF (((box.grnw*box.colors*box.sum)>bigbox))
  1477.                                 bigbox:=box.grnw*box.colors*box.sum
  1478.                                 movebox:=i
  1479.                             ENDIF
  1480.                             IF (((box.bluw*box.colors*box.sum)>bigbox))
  1481.                                 bigbox:=box.bluw*box.colors*box.sum
  1482.                                 movebox:=i
  1483.                             ENDIF
  1484.                         CASE QUANT_MEDIANCUT7
  1485.                             IF (((box.redw*box.sum)>bigbox))
  1486.                                 bigbox:=box.redw*box.colors*box.sum
  1487.                                 movebox:=i
  1488.                             ENDIF
  1489.                             IF (((box.grnw*box.sum)>bigbox))
  1490.                                 bigbox:=box.grnw*box.colors*box.sum
  1491.                                 movebox:=i
  1492.                             ENDIF
  1493.                             IF (((box.bluw*box.sum)>bigbox))
  1494.                                 bigbox:=box.bluw*box.colors*box.sum
  1495.                                 movebox:=i
  1496.                             ENDIF
  1497.                         ENDSELECT
  1498.                     ENDIF
  1499.                 ENDFOR
  1500.                 swapboxes(bv,bv+(movebox*SIZEOF box))
  1501. /*
  1502. FOR i:=0 TO boxes-1
  1503.     box:=bv+(i*SIZEOF box)
  1504.     WriteF('\n#\d[3] (\d[4] s\d[4] c\d[4]) (\d[3],\d[3])\d[3] (\d[3],\d[3])\d[3] (\d[3],\d[3])\d[3]',i,box.ind,box.sum,box.colors,box.red0,box.red1,box.redw,box.grn0,box.grn1,box.grnw,box.blu0,box.blu1,box.bluw)
  1505. ENDFOR
  1506. */
  1507.             ENDWHILE
  1508. break3:
  1509.             FOR bi:=0 TO (boxes-1)
  1510.                 box:=bv+(bi*SIZEOF box)
  1511.                 indx:=box.ind
  1512.                 clrs:=box.colors
  1513.                 SELECT QUANT_END OF mode
  1514.                 CASE QUANT_MEDIANCUT
  1515.                     r:=0;g:=0;b:=0;sum:=0
  1516.                     FOR i:=0 TO (clrs-1)
  1517.                         chi:=chv+((indx+i)*SIZEOF colorhist_item)
  1518.                         colo:=chi.color
  1519.                         r:=r+((PPM_GETR(colo)))
  1520.                         g:=g+((PPM_GETG(colo)))
  1521.                         b:=b+((PPM_GETB(colo)))
  1522.                         sum:=sum+1
  1523.                     ENDFOR
  1524.                     r:=limit(r/sum,0,255)
  1525.                     g:=limit(g/sum,0,255)
  1526.                     b:=limit(b/sum,0,255)
  1527.                 CASE QUANT_MEDIANCUT2,QUANT_MEDIANCUT3
  1528.                     r:=SpFlt(0);g:=SpFlt(0);b:=SpFlt(0);sum:=SpFlt(0)
  1529.                     FOR i:=0 TO (clrs-1)
  1530.                         chi:=chv+((indx+i)*SIZEOF colorhist_item)
  1531.                         colo:=chi.color
  1532.                         tmp1:=SpFlt(chi.value)
  1533.                         r:=SpAdd(r,SpMul(SpFlt(PPM_GETR(colo)),tmp1))
  1534.                         g:=SpAdd(g,SpMul(SpFlt(PPM_GETG(colo)),tmp1))
  1535.                         b:=SpAdd(b,SpMul(SpFlt(PPM_GETB(colo)),tmp1))
  1536.                         sum:=SpAdd(sum,tmp1)
  1537.                     ENDFOR
  1538.                     IF SpFix(sum)=0 THEN sum:=SpFlt(1)
  1539.                     r:=limit(SpFix(SpDiv(sum,r)),0,255)
  1540.                     g:=limit(SpFix(SpDiv(sum,g)),0,255)
  1541.                     b:=limit(SpFix(SpDiv(sum,b)),0,255)
  1542.                 DEFAULT
  1543.                     r:=SpFlt(0);g:=SpFlt(0);b:=SpFlt(0)
  1544.                     rsum:=SpFlt(0);gsum:=SpFlt(0);bsum:=SpFlt(0)
  1545.                     FOR i:=0 TO (clrs-1)
  1546.                         chi:=chv+((indx+i)*SIZEOF colorhist_item)
  1547.                         colo:=chi.color
  1548.                         tmp1:=SpFlt(chi.value)
  1549.                         r:=SpAdd(r,SpMul(SpFlt(PPM_GETR(colo) OR 1),tmp1));rsum:=SpAdd(rsum,tmp1)
  1550.                         g:=SpAdd(g,SpMul(SpFlt(PPM_GETG(colo)),tmp1));gsum:=SpAdd(gsum,tmp1)
  1551.                         b:=SpAdd(b,SpMul(SpFlt(PPM_GETB(colo) OR 4),tmp1));bsum:=SpAdd(bsum,tmp1)
  1552. ->                        IF mode=QUANT_MEDIANCUT2
  1553.                             IF PPM_GETR(colo)>63 AND PPM_GETR(colo)<196
  1554.                                 r:=SpAdd(r,SpMul(SpFlt(PPM_GETR(colo) OR $1),tmp1));rsum:=SpAdd(rsum,tmp1)
  1555.                             ENDIF
  1556.                             IF PPM_GETG(colo)>63 AND PPM_GETG(colo)<196
  1557.                                 g:=SpAdd(g,SpMul(SpFlt(PPM_GETG(colo)),tmp1));gsum:=SpAdd(gsum,tmp1)
  1558.                             ENDIF
  1559.                             IF PPM_GETB(colo)>63 AND PPM_GETB(colo)<196
  1560.                                 b:=SpAdd(b,SpMul(SpFlt(PPM_GETB(colo) OR 4),tmp1));bsum:=SpAdd(bsum,tmp1)
  1561.                             ENDIF
  1562. ->                        ENDIF
  1563.                     ENDFOR
  1564.                     IF SpFix(rsum)=0 THEN rsum:=SpFlt(1)
  1565.                     IF SpFix(gsum)=0 THEN gsum:=SpFlt(1)
  1566.                     IF SpFix(bsum)=0 THEN bsum:=SpFlt(1)
  1567.                     r:=limit(SpFix(SpDiv(rsum,r)),0,255)
  1568.                     g:=limit(SpFix(SpDiv(gsum,g)),0,255)
  1569.                     b:=limit(SpFix(SpDiv(bsum,b)),0,255)
  1570.                 ENDSELECT
  1571.                 chi:=colormap+(bi*SIZEOF colorhist_item)
  1572.                 chi.color:=PPM_ASSIGN(r,g,b)
  1573.             ENDFOR
  1574.         ENDIF
  1575.         Dispose(bv)
  1576.     ENDIF
  1577. ENDPROC colormap
  1578.  
  1579. PROC swapboxes(box1:PTR TO box,box2:PTR TO box)
  1580.     DEF tmp
  1581.     tmp:=box1.ind;        box1.ind:=box2.ind;                box2.ind:=tmp
  1582.     tmp:=box1.colors;    box1.colors:=box2.colors;    box2.colors:=tmp
  1583.     tmp:=box1.sum;        box1.sum:=box2.sum;                box2.sum:=tmp
  1584.     tmp:=box1.redw;        box1.redw:=box2.redw;            box2.redw:=tmp
  1585.     tmp:=box1.grnw;        box1.grnw:=box2.grnw;            box2.grnw:=tmp
  1586.     tmp:=box1.bluw;        box1.bluw:=box2.bluw;            box2.bluw:=tmp
  1587.     tmp:=box1.red0;        box1.red0:=box2.red0;            box2.red0:=tmp
  1588.     tmp:=box1.grn0;        box1.grn0:=box2.grn0;            box2.grn0:=tmp
  1589.     tmp:=box1.blu0;        box1.blu0:=box2.blu0;            box2.blu0:=tmp
  1590.     tmp:=box1.red1;        box1.red1:=box2.red1;            box2.red1:=tmp
  1591.     tmp:=box1.grn1;        box1.grn1:=box2.grn1;            box2.grn1:=tmp
  1592.     tmp:=box1.blu1;        box1.blu1:=box2.blu1;            box2.blu1:=tmp
  1593. ENDPROC
  1594.  
  1595. PROC computecolorhist(redbuf,grnbuf,blubuf,cols,rows,maxcolors,colorsP)
  1596.     DEF cht=0
  1597.     DEF chv=0
  1598.     cht:=computecolorhash(redbuf,grnbuf,blubuf,cols,rows,maxcolors,colorsP)
  1599.     IF cht
  1600.         chv:=colorhashtocolorhist(cht,maxcolors)
  1601.         freecolorhash(cht)
  1602.         RETURN chv
  1603.     ELSE
  1604.         RETURN 0
  1605.     ENDIF
  1606. ENDPROC
  1607.  
  1608. PROC computecolorhash(redbuf:PTR TO CHAR,grnbuf:PTR TO CHAR,blubuf:PTR TO CHAR,cols,rows,maxcolors,colorsP:PTR TO LONG)
  1609.     DEF cht=0:PTR TO LONG
  1610.     DEF pP=0
  1611.     DEF chl=0:PTR TO colorhist_list_item
  1612.     DEF col,row,hash,ccoolloorr
  1613.     cht:=alloccolorhash()
  1614.     IF cht
  1615.         IF colorsP
  1616.             colorsP[0]:=0
  1617.             row:=0
  1618.             REPEAT
  1619.                 IF checkcancel(statwindow)
  1620.                     freecolorhash(cht)
  1621.                     Raise("canc")
  1622.                 ENDIF
  1623.                 IF ((row/4)=((row+3)/4)) 
  1624.                     IF gaugeobj THEN fuelgauge(statwindow.rport,gaugeobj,row,rows-1,stat.histogram_string,drawinfo)
  1625.                 ENDIF
  1626.                 col:=0
  1627.                 REPEAT
  1628.                     ccoolloorr:=(PPM_PUTR(redbuf[pP]) OR PPM_PUTG(grnbuf[pP]) OR PPM_PUTB(blubuf[pP]) AND $FCFEF8)  -> Give RED 6 BITS, GRN 7 BITS, and BLU 5 BITS...this helps improve clustering, and to keep the number of unique colors below 32768 !
  1629.                     hash:=HASHPIXEL(ccoolloorr)
  1630.                     chl:=cht[hash]
  1631.                     WHILE (chl<>0)
  1632.                         IF (chl.ch.color=ccoolloorr)
  1633.                             JUMP break
  1634.                         ENDIF
  1635.                         chl:=chl.next
  1636.                     ENDWHILE
  1637. break:
  1638.                     IF (chl<>0)
  1639.                         chl.ch.value:=(chl.ch.value+1)
  1640.                     ELSE
  1641.                         colorsP[0]:=colorsP[0]+1
  1642.                         IF colorsP[0]>maxcolors
  1643.                             freecolorhash(cht)
  1644.                             RETURN 0
  1645.                         ENDIF
  1646. ->                    chl:=New(SIZEOF colorhist_list_item)
  1647.                         chl:=alloc(histopool,SIZEOF colorhist_list_item)
  1648.                         IF chl
  1649.                             chl.ch.color:=ccoolloorr
  1650.                             chl.ch.value:=1
  1651.                             chl.next:=cht[hash]
  1652.                             cht[hash]:=chl
  1653.                         ENDIF
  1654.                     ENDIF
  1655.                 col:=col+1;pP:=pP+1;UNTIL col=cols
  1656.             row:=row+1;UNTIL row=rows
  1657.         ENDIF
  1658.     ENDIF
  1659. ENDPROC cht
  1660.  
  1661. PROC alloccolorhash()
  1662.     DEF cht=0
  1663.     cht:=New((HASH_SIZE*4)+20)
  1664. ENDPROC cht
  1665.  
  1666. PROC colorhashtocolorhist(cht:PTR TO LONG,maxcolors)
  1667.     DEF chv=0:PTR TO colorhist_item
  1668.     DEF chl=0:PTR TO colorhist_list_item
  1669.     DEF i,j
  1670.     chv:=New((maxcolors*SIZEOF colorhist_item)+20)
  1671.     j:=0
  1672.     FOR i:=0 TO (HASH_SIZE-1)
  1673.         chl:=cht[i]
  1674.         WHILE (chl<>0)
  1675.             PutLong(chv+(j*SIZEOF colorhist_item),chl.ch.color)
  1676.             PutLong(chv+4+(j*SIZEOF colorhist_item),chl.ch.value)
  1677.             j:=j+1
  1678.             chl:=chl.next
  1679.         ENDWHILE
  1680.     ENDFOR
  1681. ENDPROC chv
  1682.  
  1683. PROC freecolorhash(cht)
  1684.     DEF i
  1685.     DEF chl:PTR TO colorhist_list_item
  1686.     DEF chlnext
  1687.     i:=0
  1688.     deletepool(histopool)
  1689.     Dispose(cht)
  1690. ENDPROC 0
  1691.  
  1692. PROC qsort(chv,l,r,and)
  1693.     DEF i,j,x,m1,m2
  1694.     x:=((Long(chv+((Shr(l+r,1))*SIZEOF colorhist_item))) AND and)
  1695.     i:=l
  1696.     j:=r
  1697.     REPEAT
  1698.         WHILE (((Long(chv+(i++*SIZEOF colorhist_item))) AND and) < x)
  1699.         ENDWHILE
  1700.         WHILE (x<((Long(chv+(j*SIZEOF colorhist_item))) AND and))
  1701.             j:=j-1
  1702.         ENDWHILE
  1703.         IF (i-- <=j)
  1704.             m1:=chv+(j*SIZEOF colorhist_item)
  1705.             m2:=chv+(i*SIZEOF colorhist_item)
  1706.             MOVE.L    m1,A0
  1707.             MOVE.L    m2,A1
  1708.  
  1709.             MOVE.L    (A0),D0
  1710.             MOVE.L    (A1),(A0)+
  1711.             MOVE.L    D0,(A1)+
  1712.             MOVE.L    (A0),D0
  1713.             MOVE.L    (A1),(A0)
  1714.             MOVE.L    D0,(A1)
  1715.             i:=i+1
  1716.             DEC j
  1717.         ENDIF
  1718.     UNTIL i>j
  1719.     IF l<j THEN qsort(chv,l,j,and)
  1720.     IF i<r THEN qsort(chv,i,r,and)
  1721. ENDPROC
  1722.  
  1723. PROC doexchange(cmap,pen,r,g,b,uhp)
  1724.     DEF newpen
  1725.     newpen:=findcolorbytes(cmap,r,g,b,uhp)
  1726.     exchangecolorcmap(cmap,pen,newpen)
  1727. ENDPROC
  1728.  
  1729. PROC sizebox(box:PTR TO box,chv)
  1730.     DEF i,ptr:PTR TO colorhist_item
  1731.     DEF mr=255,mg=255,mb=255,xr=0,xg=0,xb=0
  1732.     DEF color,r,g,b
  1733.     ptr:=chv+(box.ind*SIZEOF colorhist_item)
  1734.     FOR i:=0 TO box.colors-1
  1735.         color:=ptr.color
  1736.         MOVE.L    color,D0
  1737.         MOVE.L    D0,D1
  1738.         AND.L        #$FF,D1
  1739.         MOVE.L    D1,b
  1740.         LSR.L        #8,D0
  1741.         MOVE.L    D0,D1
  1742.         AND.L        #$FF,D1
  1743.         MOVE.L    D1,g
  1744.         LSR.L        #8,D0
  1745.         MOVE.L    D0,D1
  1746.         AND.L        #$FF,D1
  1747.         MOVE.L    D1,r
  1748.         IF (r<mr) THEN mr:=r
  1749.         IF (g<mg) THEN mg:=g
  1750.         IF (b<mb) THEN mb:=b
  1751.         IF (r>xr) THEN xr:=r
  1752.         IF (g>xg) THEN xg:=g
  1753.         IF (b>xb) THEN xb:=b
  1754.         ptr:=ptr+SIZEOF colorhist_item
  1755.     ENDFOR
  1756.     box.redw:=xr-mr
  1757.     box.grnw:=xg-mg
  1758.     box.bluw:=xb-mb
  1759.     box.red0:=mr
  1760.     box.grn0:=mg
  1761.     box.blu0:=mb
  1762.     box.red1:=xr
  1763.     box.grn1:=xg
  1764.     box.blu1:=xb
  1765. ->    WriteF('\n (\d,\d ---\d) (\d,\d ---\d) (\d,\d ---\d)',box.red0,box.red1,box.redw,box.grn0,box.grn1,box.grnw,box.blu0,box.blu1,box.bluw)
  1766. ENDPROC
  1767.  
  1768. PROC mergesize(sizestruct:PTR TO sizestruct,pixw,pixh,redbuf:PTR TO CHAR,grnbuf:PTR TO CHAR,blubuf:PTR TO CHAR,bufw,bufh)
  1769.     DEF cursx,cursy
  1770.     DEF charptr,i,t,x,y,w=0,h=0,tw=0,th=0,ii,tt
  1771.     DEF sizestr[100]:STRING
  1772.     DEF str[10]:STRING
  1773.     DEF mergebuf:PTR TO CHAR,font:PTR TO CHAR,offx
  1774.     DEF br,bg,bb,p
  1775.     mergebuf:=New(8000)
  1776.     StringF(sizestr,'\dx\d',pixw,pixh)
  1777.     
  1778.     FOR i:=0 TO (StrLen(sizestr)-1)
  1779.         w,h:=getfontwh(sizestruct.font,sizestr[i])
  1780.         tw:=tw+w
  1781.         th:=bigger(th,h)
  1782.     ENDFOR
  1783.     IF sizestruct.x=-1 THEN sizestruct.x:=(bufw/2)-(tw/2)
  1784.     IF sizestruct.y=-1 THEN sizestruct.y:=(bufh-th-2)
  1785.     offx:=1;tw:=tw+2;th:=th+2
  1786.     FOR i:=0 TO (StrLen(sizestr)-1)
  1787.         w,h,font:=getfontwh(sizestruct.font,sizestr[i])
  1788.         FOR tt:=0 TO (h-1)
  1789.             FOR ii:=0 TO (w-1)
  1790.                 mergebuf[ii+offx+((tt+1)*tw)]:=font[ii+(tt*w)]
  1791.             ENDFOR
  1792.         ENDFOR
  1793.         offx:=offx+w
  1794.     ENDFOR
  1795.     FOR ii:=0 TO tw-1
  1796.         FOR tt:=0 TO th-1
  1797.             p:=sizestruct.x+ii+(tt*bufw)+(sizestruct.y*bufw)
  1798.             IF p>=0
  1799.                 IF (p<(bufw*bufh))
  1800.                     br:=redbuf[p]
  1801.                     bg:=grnbuf[p]
  1802.                     bb:=blubuf[p]
  1803.                     i:=Char(mergebuf+ii+(tt*tw))
  1804.                     IF sizestruct.type=TEXT_SHADOW
  1805.                         br:=limit(((br+i)/2),0,255)
  1806.                         bg:=limit(((bg+i)/2),0,255)
  1807.                         bb:=limit(((bb+i)/2),0,255)
  1808.                     ELSE
  1809.                         br:=i
  1810.                         bg:=i
  1811.                         bb:=i
  1812.                     ENDIF
  1813.                     redbuf[p]:=br
  1814.                     grnbuf[p]:=bg
  1815.                     blubuf[p]:=bb
  1816.                 ENDIF
  1817.             ENDIF
  1818.         ENDFOR
  1819.     ENDFOR
  1820. ENDPROC
  1821.  
  1822. PROC getfontwh(font:PTR TO CHAR,chr)
  1823.     DEF fw,fh,i
  1824.     IF ((chr<"0") OR (chr>"9")) THEN chr:=("9"+1)
  1825.     IF chr>"0"
  1826.         FOR i:=0 TO ((chr-"0")-1)
  1827.             fw:=font[0];fh:=font[1]
  1828.             font:=(font+(fw*fh)+2)
  1829.         ENDFOR
  1830.     ENDIF
  1831.     fw:=font[0];fh:=font[1]
  1832.     font:=font+2
  1833. ENDPROC fw,fh,font
  1834.  
  1835. PROC fuelgauge(rport,gaugeobj,level,top,string,drawinfo)
  1836.     SetAttrsA(gaugeobj,
  1837.          [IA_DATA,string,
  1838.             GAUGEIA_TOP,top,
  1839.             GAUGEIA_CURLEVEL,level,
  1840.             GAUGEIA_BOTTOM,0,
  1841.             TAG_END])
  1842.     DrawImageState(rport,gaugeobj,0,0,IDS_NORMAL,drawinfo)
  1843. ENDPROC
  1844.